package cn.git.agent.transformer;

import cn.git.agent.collects.ControllerCollect;
import cn.git.agent.init.BasicCollect;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.LoaderClassPath;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.List;

/**
 * @description: 探针执行类
 * @program: bank-credit-sy
 * @author: lixuchun
 * @create: 2024-03-15 04:00:05
 */
@Data
@NoArgsConstructor
public class RuntimeTransformer implements ClassFileTransformer {

    /**
     * 探针扫描的包集合
     */
    private static List<BasicCollect> basicCollectList;

    static {
        basicCollectList = new ArrayList<>();
        basicCollectList.add(ControllerCollect.getInstance());
    }

    /**
     * 探针执行,循环多次,选择自己需要修改的类进行自定义修改
     * @param loader
     * @param className
     * @param classBeingRedefined
     * @param protectionDomain
     * @param classfileBuffer
     * @return
     * @throws IllegalClassFormatException
     */
    @Override
    public byte[] transform(ClassLoader loader,
                            String className,
                            Class<?> classBeingRedefined,
                            ProtectionDomain protectionDomain,
                            byte[] classfileBuffer) throws IllegalClassFormatException {
        // 判定不需要转换的类，进行排除
        className = className.replaceAll("/", ".");
        if (className.startsWith("sun.")
                || className.contains("$Proxy")
                || className.startsWith("org.apache.")
                || className.startsWith("javax.management.")
                || className.startsWith("com.alibaba.")
                || className.startsWith("org.springframework.")
                || className.startsWith("com.intellij.rt.")
                || className.startsWith("org.xml.")
                || className.startsWith("javax.")
                || className.startsWith("org.junit.")
                || className.startsWith("org.testng.")
                || className.startsWith("com.sun.")
                || className.startsWith("org.slf4j.")
                || className.startsWith("org.w3c.")
                || className.startsWith("jdk.internal.org.")
                || className.startsWith("java.")) {
            return classfileBuffer;
        }

        // 判断是否需要修改
        ClassPool classPool = new ClassPool();
        classPool.insertClassPath(new LoaderClassPath(loader));
        try {
            CtClass ctClass = classPool.get(className);
            for (BasicCollect basicCollect : basicCollectList) {
                if (basicCollect.isTarget(className, loader, ctClass)) {
                    return basicCollect.transform(loader, className, classfileBuffer, ctClass);
                }
            }
        } catch (Exception e) {
            System.out.println(className + " 加载失败!!!!!!");
        }
        return classfileBuffer;
    }

}
